<template>
  <div class="list-page">
    <tool-bar nav="K8s-SSH同步到生产" class="imp-prod">
      <el-button @click="clear_click">清除!</el-button>

    </tool-bar>

    <my-list
        ref="list"
        url="/ops/k8s-ssh/list-test-prod"
        @param="preload"
        @loaded="procData"
        :store="true"
        :row-class-name="rowClass"
        row-key="id"
        :query="$data.query"
        multi-check
        :page-size="$data.pageSize"
    >

      <template #pager>
        <div style="flex:1">
          <el-button size="small" @click="gen_click" :disabled="list && !list.getSelectionRows().length">生成
          </el-button>
        </div>
        <selector :data="[10,20,50,100,200,500]" v-model="$data.pageSize"></selector>
      </template>

      <el-table-column label="名称" align="left" width="240">
        <template v-slot="scope">
          <div>{{ scope.row.name }}</div>
        </template>
      </el-table-column>
      <!--      <el-table-column align="left" label="镜像名" prop="imageName" min-width="240"></el-table-column>-->
      <el-table-column align="left" label="测试环境版本" min-width="240">
        <template v-slot="scope">

          <el-tag type="danger" v-if="!scope.row.imageVersion">
            无
          </el-tag>
          <el-tag v-else>{{ scope.row.imageVersion }}</el-tag>

          <el-tag type="danger" v-if="!scope.row?.readyReplicas && scope.row.imageVersion" style="margin-left:2px;">
            0/{{ scope.row.replicas }}
          </el-tag>

        </template>
      </el-table-column>
      <el-table-column align="left" label="生产环境版本" min-width="180">
        <template v-slot="scope">
          <div @click="refresh_prod(scope.row)" class="btn" title="点击刷新数据">
            <el-tag type="warning" v-if="!scope.row.prod.version">
              无
            </el-tag>
            <el-tag v-else-if="scope.row.prod.version  == scope.row.imageVersion">
              {{ scope.row.prod.version }}
            </el-tag>
            <el-tag type="warning" v-else-if="scope.row.prod.version != scope.row.imageVersion">
              {{ scope.row.prod.version }}
            </el-tag>

            <el-tag type="danger" v-if="scope.row.prod.version &&  !scope.row?.prod?.readyReplicas  "
                    style="margin-left:2px;">0/{{ scope.row.prod.replicas }}
            </el-tag>
            <el-tag type="danger"
                    v-else-if="scope.row.prod.version &&  scope.row?.prod?.readyReplicas != scope.row?.prod?.replicas "
                    style="margin-left:2px;">{{ scope.row?.prod?.readyReplicas }}/{{ scope.row.prod.replicas }}
            </el-tag>
          </div>

        </template>
      </el-table-column>
      <el-table-column label="差距" align="left" class-name="cell-flex" width="120">
        <template v-slot="scope">
          <div v-if="!scope.row.imageVersion || !scope.row.prod.version">
          </div>
          <el-tag v-else-if="scope.row.diff_ver" :type="scope.row.diff_ver.endsWith('后')? 'danger':'primary' ">
            {{ scope.row.diff_ver }}
          </el-tag>
          <div v-else>✅</div>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="260">
        <template v-slot="scope">
          <el-space wrap :size="20">
            <el-button-group type="warning" size="small">
              <el-button @click="sync_click(scope.row)">
                仅同步
              </el-button>
              <el-button :icon="View" @click="sync_view(scope.row)">
              </el-button>
              <div v-if="scope.row.syncStatus">
                {{ scope.row.syncStatus }}
              </div>
            </el-button-group>


            <el-button-group type="danger" size="small">
              <el-button @click="sync_to_prod(scope.row)" :disabled="$data.syncing">
                到生产!
              </el-button>
              <el-button :icon="View" @click="depoly_view(scope.row)">
              </el-button>
              <div v-if="scope.row.deployStatus">
                {{ scope.row.deployStatus }}
              </div>
            </el-button-group>
          </el-space>
        </template>
      </el-table-column>
      <template #query="scope">

        <kv label="语言">
          <selector v-model="scope.query.language" enum="JenkinsLanguageEnum" clearable></selector>
        </kv>

        <kv label="名称空间">
          <el-input v-model="scope.query.namespace"></el-input>
        </kv>

        <kv label="名称">
          <el-input v-model="scope.query.name"></el-input>
        </kv>

        <kv label="状态">
          <selector v-model="scope.query.isReady" :data="{true:'就绪',false:'异常','':'全部'}"></selector>
        </kv>
      </template>

      <template #button>
        <el-button @click="loadData">刷新</el-button>
      </template>
    </my-list>

    <el-tabs type="border-card" closable v-model="$data.currentName" @tab-click="log_tab_click">
      <clock v-if="$data.working" style="background-color: #f2ef8e;position: absolute;right:0;"></clock>
      <el-tab-pane v-for="(value, key) in $data.logTxts" :name="key" :key="key"
                   style="padding:0;margin:-15px;">

        <!-- 使用 #label 插槽自定义 tab 标签 -->
        <template #label>
        <span :class="value.type">
          {{ key }}
        </span>
        </template>

        <pre
            :class="value.isError ? 'error': 'console'"
            v-html="value.content"></pre>
      </el-tab-pane>
    </el-tabs>

    <div style="margin-bottom: 20px"></div>
  </div>
</template>

<script setup>

import {
  View
} from '@element-plus/icons-vue'
/**
 * Created by CodeGenerator at 2021-03-14 15:58:11
 */
import productLine from "@/component/product-line.vue";
import appEnv from "@/component/app-env.vue"


//定义 vue2的this,当前组件
const $self = getCurrentInstance();

//定义 $attrs
const $attrs = useAttrs();


//定义data
const $data = reactive(
    {
      "target_dlg": false,
      "target": {"istio": false, "referK8sEnv": "", "k8sApiHost": "", "k8sNamespace": "default", "envProfile": "test"},
      "target_edit": {
        "istio": false,
        "referK8sEnv": "",
        "k8sApiHost": "",
        "k8sNamespace": "default",
        "envProfile": "test"
      },
      "products": [],
      "list": [],
      "query": {"language": "Java", "productLineCode": "", "targetEnv": ""},
      "sourceK8sApiHost": "",
      logTxts: {},
      syncing: false,
      exportTxt: "",
      pageSize: 10,
      currentName: "",
      working: false
    });


const $props = defineProps({});


const list = ref();

//定义事件
const $emit = defineEmits(["update:modelValue", "loaded"]);


const gen_click = () => {
  var rows = list.value.getSelectionRows();
  if (!rows.length) {
    return jv.info("请选择镜像");
  }

  /*
  function docker-push() {
    imgver=$1
    docker pull harbor.huatuocloud.com:7443/$imgver
    docker tag  harbor.huatuocloud.com:7443/$imgver  reg2.huatuocloud.com/$imgver

    echo "docker push reg2.huatuocloud.com/$imgver"
    docker push reg2.huatuocloud.com/$imgver
  }
   */
  $data.exportTxt = ".8上执行 source docker-tools.sh \n" + rows.map(it => `docker-push  ${it.imageNameVersion}`).join("\n") + "<hr />" +
      "server上执行:\n" +
      rows.map(it => `kubectl set image deployment/${it.name.padEnd(16)}  reg2.huatuocloud.com/${it.imageNameVersion}`).join("\n")
}

const env_change = function (v, m) {
  $data.sourceK8sApiHost = m && m.url || "";
};

const rowClass = function (rowOpt) {
  return "row-" + rowOpt.row.name.split('-').getLast()
};
const bind_target_click = function () {
  $data.target_dlg = true;
  $data.target_edit = Object.assign({}, $data.target);
};
const export_click = function () {
  jv.info("未实现")
};

const refresh_prod = function (row) {
  jv.$http.post("/ops/k8s-ssh/fetch-prod-version", {namespace: $data.query.namespace, name: row.name})
      .then(res => {
        var json = res.data.data;
        row.prod.version = json.imageVersion;
        row.prod.replicas = json.replicas;
        row.prod.readyReplicas = json.readyReplicas
      });
};

// const deploy_to_prod = function (row) {
//   $data.sync_done_number = 0;
//   $data.syncing = true;
//   jv.prompt("镜像:版本号", "输入格式").then(res => {
//     if (res.value) {
//       jv.$http.post("/ops/k8s-ssh/sync-to-prod", {namespace: $data.query.namespace, name: row.name, image: res.value})
//           .then(res => {
//             jv.alert("部署 " + row.name + " 成功!<br />");
//             loadData()
//           })
//           .finally(() => {
//             $data.syncing = false;
//           });
//     }
//   }).catch(it => {
//     $data.syncing = false;
//   })
//
// }


const log_tab_click = function () {
  if (!$data.currentName) {
    return;
  }

  if (!$data.logTxts[$data.currentName]) {
    return;
  }

  $data.logTxts[$data.currentName].isDone = false
}

const clear_click = () => {
  jv.$http.post("/ops/k8s-ssh/clear-sync");
}

const setWorkingQueue = list => {
  $data.list.data.forEach(it => {
    it.syncStatus = ""
    it.deployStatus = ""
  })

  var index = -1;
  list.forEach(it => {
    index++;

    var sect = it.split(":");
    var type = sect[0]
    if (sect.length != 3) {
      return
    }

    var name = sect[2];
    var dbOne = $data.list.data.find(it => it.name == name);
    if (!dbOne) {
      return;
    }

    if (index == 0) {
      dbOne[type + "Status"] = "进行中"
    } else {
      dbOne[type + "Status"] = "队列中"
    }
  })
}

const getLog = () => {

  if (document.hidden) {
    return;
  }

  if (!$data.currentName) {
    return;
  }

  if ($data.logTxts[$data.currentName].isDone) {
    return;
  }

  var type = $data.logTxts[$data.currentName].type;

  var name = $data.currentName;
  $data.working = true;

  jv.$http.get("/ops/k8s-ssh/get-sync-log?name=" + name, {msgIsError: false})
      .then(res => {
        if (res.data.msg) {
          $data.working = false;
          $data.logTxts[name] = {content: res.data.msg, type, isDone: true, isError: true};
          return;
        }

        setWorkingQueue(res.data.value);

        var content = res.data.data;
        if (!content) {
          return;
        }
        var version = $data.logTxts[name].version;

        var lines = content.split("\n");
        var firstLine = lines[0];
        if (!firstLine.endsWith(":" + version)) {
          return;
        }

        var lastLine = lines.filter(it => it).getLast();
        var isDone = (lastLine == `[${type} done]` || lastLine == `[deploy done]`);
        $data.logTxts[$data.currentName] = {content, version, type, isDone};


        if (isDone) {
          $data.working = false;

          $data.list.data.forEach(it => {
            it.syncStatus = ""
            it.deployStatus = ""
          })

          var row = list.value.getData().data.getLast(it => it.name == $data.currentName);
          if (row) {
            refresh_prod(row)
          }
        }
      })
}

const sync_click = function (row) {
  $data.sync_done_number = 0;
  $data.syncing = true;
  jv.$http.post("/ops/k8s-ssh/only-sync", {namespace: $data.query.namespace, name: row.name})
      .then(res => {
        setTimeout(() => {
          $data.currentName = row.name
          $data.logTxts[$data.currentName] = {content: "", type: "sync", version: row.imageVersion};
        }, 1000);
      })
      .finally(() => {
        $data.syncing = false;
      });
}

/**
 * 同步镜像到生产
 * @param row
 */
const sync_to_prod = function (row) {
  $data.sync_done_number = 0;
  $data.syncing = true;
  jv.$http.post("/ops/k8s-ssh/sync-to-prod", {namespace: $data.query.namespace, name: row.name})
      .then(res => {
        $data.currentName = row.name
        $data.logTxts[$data.currentName] = {content: "", type: "deploy", version: row.imageVersion};
      })
      .finally(() => {
        $data.syncing = false;
      });
};
const preload = function (param, callback) {
  if (!list.value.$refs.query.chk()) {
    return callback(false);
  }
//添加查询参数，修改分页参数等。
//param.type = jv.$route.params.type
};
const procData = function (res) {
  res.data.data.forEach(row => {

    row.id = row.name;
    row.imageVersion = row.imageNameVersion.split(":").getLast()
    if (!row.prod.version) {
      row.diff_ver = "";
    } else {
      row.diff_ver = jv.getTimeDiffSummary(Date.from(row.prod.version) - Date.from(row.imageVersion))
    }
  })

  $data.list = res.data;
};

const loadData = function (pageNumber) {
  list.value.loadData(pageNumber);
};
const sync_view = function (row) {
  $data.currentName = row.name;
  $data.logTxts[$data.currentName] = {content: "", type: "sync", version: row.imageVersion, isDone: false};
};

const depoly_view = function (row) {
  $data.currentName = row.name;
  $data.logTxts[$data.currentName] = {content: "", type: "deploy", version: row.imageVersion, isDone: false};
};


onMounted(function () {
  jv.$loadData("target", v => $data.target = v)
  jv.$loadData("query", v => $data.query = v)

  setInterval(getLog, 1500);
})


</script>

<style scoped lang="scss">
pre {
  background-color: rgb(32 32 32);
  color: white;
  padding: 5px;
  border-radius: 5px;
  max-height: 300px;
  min-height: 100px;
}

pre.error {
  color: red;
}


.btn {
  display: inline-block;
  cursor: pointer;
  margin-right: 8px;
}

.btn:hover span {
  opacity: 0.8;
  border-bottom: solid 1px gray;
}

::v-deep(tr.row-java) .cell-name {
  color: #1e4a90;
}

::v-deep(tr.row-vue) .cell-name {
  color: #694002;
}

::v-deep(tr.row-node) .cell-name {
  color: #286f04;
}


.imp-prod ::v-deep(.last) * {
  zoom: 1.1;
  background-color: red !important;
  color: white !important;
  border-radius: 4px;
  padding: 4px 6px;
}

::v-deep([role="tab"] .sync) {

  &::before {
    content: " ";
    position: absolute;
    display: block;
    left: 0;
    top: 0;
    width: 0;
    height: 0;
    border-top: 25px solid #E6A23C;
    border-right: 50px solid transparent;
  }

}


::v-deep([role="tab"] .deploy) {

  &::before {
    content: "";
    position: absolute;
    display: block;
    left: 0;
    top: 0;
    width: 0;
    height: 0;
    border-top: 25px solid #F56C6C;
    border-right: 50px solid transparent;
  }
}

</style>